! ****************************************************************
!doc    I4DATE RETURNS I4 DATE (# OF DAYS SINCE 01-JAN-0000)
!doc    GIVEN 4 INTEGERS CONTAINING YEAR, MONTH, DAY
!
! ****************************************************************
        FUNCTION I4DATE (NYEAR,NMONTH,NDAY)
        IMPLICIT NONE

        INTEGER*4 I4DATE
        INTEGER*4 NYEAR, NMONTH, NDAY
!
        INTEGER*4 NDAYYR, NDAYDA
        INTEGER*4 NYR, NYRS, NLEAP,BSLEAP,YRLEAP
        INTEGER*4 NDAYS(12), NDAYMO(12)
        INTEGER*4 IBASE, ISUM, I
        PARAMETER (IBASE=0)

        DATA NDAYYR/365/NDAYDA/1/
        DATA NDAYMO/31,28,31,30,31,30,31,31,30,31,30,31/
        DATA NDAYS/31,28,31,30,31,30,31,31,30,31,30,31/
 
!================================================================

! Sum the number of years.

        NYR=NYEAR
        IF (NYR.LT.100) THEN 
          IF (NYR.GT.50) THEN 
            NYR=NYR+1900 
          ELSE
            NYR=NYR+2000
          END IF
        END IF 
        NYRS=NYR-IBASE
!        IF (NYRS.LT.0.OR.NYRS.GT.67) GO TO 1000
        IF (NYRS.LT.0) GO TO 1000
        ISUM=NYRS*NDAYYR

        BSLEAP=(IBASE/4)-(IBASE/100)+(IBASE/400)
        YRLEAP=(NYR/4)-(NYR/100)+(NYR/400)
        NLEAP=YRLEAP-BSLEAP             ! Account for leap years.

        ISUM=ISUM+(NLEAP*NDAYDA)
!
! Sum in the number of months.
!
        IF (NMONTH.LT.1.OR.NMONTH.GT.12) GO TO 1000
!
        IF (NMONTH.NE.1) THEN
                DO I=1,NMONTH-1
                        ISUM=ISUM + NDAYMO(I)
                END DO
        END IF
!
! Correct for Jan or Feb of a leap yer.
!
!        IF (MOD(NYRS,4).EQ.0) THEN
!        IF (MOD(NYR,4).EQ.0) THEN       ! Steve Albers, Linda Wharton 1993
!          IF (NMONTH.LE.2) ISUM=ISUM-NDAYDA
!        END IF
        IF (MOD(NYR,4).EQ.0 .AND. &
            (MOD(NYR,400).EQ.0 .OR. MOD(NYR,100).NE.0)) THEN
          YRLEAP=1
        ELSE
          YRLEAP=0
        END IF

        IF (YRLEAP.EQ.1) THEN
          IF (NMONTH.LE.2) ISUM=ISUM-NDAYDA
        END IF 
!
! Sum in the number of days.
!
        IF (NDAY.LT.1.OR.NDAY.GT.(NDAYS(NMONTH)+YRLEAP))  &
        GO TO 1000
        ISUM=ISUM+((NDAY-1)*NDAYDA)
!
!
        I4DATE=ISUM+1    ! including the first day of 1,JAN,0000  
        RETURN
!
! Return error code.
!
1000    I4DATE=-1
        WRITE(6,*) 'Error in FUNCTION I4DATE'
        RETURN
!
        END FUNCTION I4DATE

! *****************************************************************
!
!       GMDATE RETURNS INTEGERS CONTAINING YEAR,MONTH,DAY,STATUS 
!       GIVEN a INTEGER OF I4DATE (# OF DAYS SINCE 01-JAN-0000) 
!
! *****************************************************************
        SUBROUTINE GMDATE (I4DATE,NYEAR,NMONTH,NDAY,STATUS)
        IMPLICIT NONE 

        INTEGER*4 I4DATE
        INTEGER*4 NYEAR, NMONTH, NDAY, STATUS
!
        INTEGER*4 NDAYYR, NDAYDA
        INTEGER*4 NLEAP, YRLEAP, NLEFT
        INTEGER*4 VDAYMO(12), NDAYMO(12)
!        INTEGER*4 BASE 
!        PARAMETER (BASE = 0)

        DATA NDAYYR/365/NDAYDA/1/
        DATA NDAYMO/31,28,31,30,31,30,31,31,30,31,30,31/
!
!================================================================
!
        STATUS = 0
        VDAYMO=NDAYMO
!
! Sum the number of years.
!
        NLEFT=I4DATE
        NYEAR=NLEFT/(NDAYYR+NDAYDA)
        NLEAP=(NYEAR/4)-(NYEAR/100)+(NYEAR/400)    ! Account for leap years.
!        NLEFT=NLEFT-NYEAR*(NDAYYR+HRDA)+(NYEAR-NLEAP)*NDAYDA
        NLEFT=NLEFT-NYEAR*NDAYYR-NLEAP*NDAYDA

        IF (MOD(NYEAR,4).EQ.0 .AND. &
            (MOD(NYEAR,400).EQ.0 .OR. MOD(NYEAR,100).NE.0)) THEN      
          !NLEFT=NLEFT+NDAYDA                  ! make up the leap year
          YRLEAP=1
        ELSE 
          YRLEAP=0
        END IF
    
        DO WHILE (NLEFT.GE.(NDAYYR+YRLEAP*NDAYDA))
          NYEAR=NYEAR+1
          NLEFT=NLEFT-NDAYYR-YRLEAP*NDAYDA 
          YRLEAP=0
          IF (MOD(NYEAR,4).EQ.0 .AND. &
              (MOD(NYEAR,400).EQ.0 .OR. MOD(NYEAR,100).NE.0)) THEN      
            YRLEAP=1
          ELSE
            YRLEAP=0
          END IF
        END DO 

!
! count the number of months.
! 
        NMONTH=1
        IF (MOD(NYEAR,4).EQ.0 .AND. &
            (MOD(NYEAR,400).EQ.0 .OR. MOD(NYEAR,100).NE.0)) THEN
          VDAYMO(2)=NDAYMO(2)+NDAYDA
        ELSE
          VDAYMO(2)=NDAYMO(2)
        END IF
        DO WHILE (NLEFT.GE.VDAYMO(NMONTH)) 
          NLEFT=NLEFT-VDAYMO(NMONTH)
          NMONTH=NMONTH+1
        END DO 
        
!
! Sum in the number of days.
!
        NDAY=NLEFT

        END SUBROUTINE GMDATE
       
! *****************************************************************
!  RETRUN SECONDS OF TIME1-TIME2(IN FORMAT: YYYY-MM-DD_HH:mm:ss)
!  YYYY: FOUR DIGITS OF YEAR 
!  MM  : TWO DIGITS OF MONTH 
!  DD  : TWO DIGITS OF DAY 
!  HH  : TWO DIGITS OF HOUR
!  mm  : TWO DIGITS OF MINUTE    
!  ss  : TWO DIGITS OF SECOND
! *****************************************************************
        FUNCTION MINUS_TIME(TIME1,TIME2)
        IMPLICIT NONE 
        INTEGER MINUS_TIME,I4DATE 
        CHARACTER*19 TIME1,TIME2
        INTEGER IDATE1(6),IDATE2(6)
        INTEGER DAYS1,DAYS2
        
        CALL READ_DATE(TIME1,IDATE1)
        CALL READ_DATE(TIME2,IDATE2)
 
        DAYS1=I4DATE(IDATE1(1),IDATE1(2),IDATE1(3))
        DAYS2=I4DATE(IDATE2(1),IDATE2(2),IDATE2(3))
        MINUS_TIME=(DAYS1-DAYS2)*86400+(IDATE1(4)-IDATE2(4))*3600 &
                   +(IDATE1(5)-IDATE2(5))*60+(IDATE1(6)-IDATE2(6))
        RETURN 
        END FUNCTION MINUS_TIME

! *****************************************************************
!   Read time value include year, month, day, hour, minute, second 
!   from hdate sting (of YYYY-MM-DD_HH:mm:ss)
! *****************************************************************
        SUBROUTINE READ_DATE(hdate,IDATE)
        implicit none 
        integer IDATE(6)
        integer year,month,day, hour, minute,second
        character*19 hdate

        read(hdate(1:4),'(I4)') year
        read(hdate(6:7),'(I2)') month
        read(hdate(9:10),'(I2)') day
        read(hdate(12:13),'(I2)') hour
        read(hdate(15:16),'(I2)') minute
        read(hdate(18:19),'(I2)') second
        IDATE(1)=year
        IDATE(2)=month
        IDATE(3)=day
        IDATE(4)=hour
        IDATE(5)=minute
        IDATE(6)=second
        return
        END SUBROUTINE READ_DATE

        FUNCTION I4HOUR (NYEAR,NMONTH,NDAY,NHOUR)
!
!doc    I4HOUR RETURNS I4 TIME (# OF HOURS SINCE 00 01-JAN-0000)
!doc    GIVEN 4 INTEGERS CONTAINING YEAR, MONTH, DAY, HOUR
!
!================================================================
        IMPLICIT NONE

        INTEGER*4 I4HOUR
        INTEGER*4 NYEAR, NMONTH, NDAY, NHOUR
!
        INTEGER*4 NHRYR, NHRDA
        INTEGER*4 NYR, NYRS, NLEAP,BSLEAP,YRLEAP
        INTEGER*4 NDAYS(12), NHRMO(12)
        INTEGER*4 IBASE, ISUM, I
        PARAMETER (IBASE=0)

        DATA NHRYR/8760/NHRDA/24/
        DATA NHRMO/744,672,744,720,744,720,744,744,720,744,720,744/
        DATA NDAYS/31,28,31,30,31,30,31,31,30,31,30,31/
!
!================================================================
!
!
! Sum the number of years.
!
        NYR=NYEAR
        IF (NYR.LT.100) THEN 
          IF (NYR.GT.50) THEN 
            NYR=NYR+1900 
          ELSE
            NYR=NYR+2000
          END IF
        END IF 
        NYRS=NYR-IBASE
!        IF (NYRS.LT.0.OR.NYRS.GT.67) GO TO 1000
        IF (NYRS.LT.0) GO TO 1000
        ISUM=NYRS*NHRYR

        BSLEAP=(IBASE/4)-(IBASE/100)+(IBASE/400)
        YRLEAP=(NYR/4)-(NYR/100)+(NYR/400)
        NLEAP=YRLEAP-BSLEAP             ! Account for leap years.

        ISUM=ISUM+(NLEAP*NHRDA)
!
! Sum in the number of months.
!
        IF (NMONTH.LT.1.OR.NMONTH.GT.12) GO TO 1000
!
        IF (NMONTH.NE.1) THEN
                DO I=1,NMONTH-1
                        ISUM=ISUM + NHRMO(I)
                END DO
        END IF
!
! Correct for Jan or Feb of a leap yer.
!
!        IF (MOD(NYRS,4).EQ.0) THEN
!        IF (MOD(NYR,4).EQ.0) THEN       ! Steve Albers, Linda Wharton 1993
!          IF (NMONTH.LE.2) ISUM=ISUM-NHRDA
!        END IF
        IF (MOD(NYR,4).EQ.0 .AND. &
            (MOD(NYR,400).EQ.0 .OR. MOD(NYR,100).NE.0)) THEN
          YRLEAP=1
        ELSE
          YRLEAP=0
        END IF

        IF (YRLEAP.EQ.1) THEN
          IF (NMONTH.LE.2) ISUM=ISUM-NHRDA
        END IF 
!
! Sum in the number of days.
!
        IF (NDAY.LT.1.OR.NDAY.GT.(NDAYS(NMONTH)+YRLEAP))  &
        GO TO 1000
        ISUM=ISUM+((NDAY-1)*NHRDA)
!
! Sum in the number of hours.
!
        IF (NHOUR.LT.0.OR.NHOUR.GT.23) GO TO 1000
        ISUM=ISUM+NHOUR

!
!
        I4HOUR=ISUM
        RETURN
!
! Return error code.
!
1000    I4HOUR=-1
        WRITE(6,*) 'Error in FUNCTION I4HOUR'
        RETURN
!
        END

!************************************************************************
!
!       GMHOUR RETURNS INTEGERS CONTAINING YEAR,MONTH,DAY,HOUR 
!       AND STATUS 
!       GIVEN a INTEGER OF I4HOUR (# OF HOURS SINCE 00 01-JAN-0000) 
!
!================================================================
        SUBROUTINE GMHOUR (I4HOUR,NYEAR,NMONTH,NDAY,NHOUR,STATUS)
        IMPLICIT NONE 

        INTEGER*4 I4HOUR
        INTEGER*4 NYEAR, NMONTH, NDAY, NHOUR, STATUS
!
        INTEGER*4 NHRYR, NHRDA
        INTEGER*4 NLEAP, YRLEAP, NLEFT
        INTEGER*4 VHRMO(12), NHRMO(12)
!        INTEGER*4 BASE 
!        PARAMETER (BASE = 0)

        DATA NHRYR/8760/NHRDA/24/
        DATA NHRMO/744,672,744,720,744,720,744,744,720,744,720,744/
!
!================================================================
!
        STATUS = 0
        VHRMO=NHRMO
!
! Sum the number of years.
!
        NYEAR=I4HOUR/(NHRYR+NHRDA)
        NLEAP=(NYEAR/4)-(NYEAR/100)+(NYEAR/400)    ! Account for leap years.
!        NLEFT=I4HOUR-NYEAR*(NHRYR+HRDA)+(NYEAR-NLEAP)*NHRDA
        NLEFT=I4HOUR-NYEAR*NHRYR-NLEAP*NHRDA

        IF (MOD(NYEAR,4).EQ.0 .AND. &
            (MOD(NYEAR,400).EQ.0 .OR. MOD(NYEAR,100).NE.0)) THEN      
          !NLEFT=NLEFT+NHRDA                  ! make up the leap year
          YRLEAP=1
        ELSE 
          YRLEAP=0
        END IF
    
        DO WHILE (NLEFT.GE.(NHRYR+YRLEAP*NHRDA))
          NYEAR=NYEAR+1
          NLEFT=NLEFT-NHRYR-YRLEAP*NHRDA 
          YRLEAP=0
          IF (MOD(NYEAR,4).EQ.0 .AND. &
              (MOD(NYEAR,400).EQ.0 .OR. MOD(NYEAR,100).NE.0)) THEN      
            YRLEAP=1
          ELSE
            YRLEAP=0
          END IF
        END DO 

!
! count the number of months.
! 
        NMONTH=1
        IF (MOD(NYEAR,4).EQ.0 .AND. &
            (MOD(NYEAR,400).EQ.0 .OR. MOD(NYEAR,100).NE.0)) THEN
          VHRMO(2)=NHRMO(2)+NHRDA
        ELSE
          VHRMO(2)=NHRMO(2)
        END IF
        DO WHILE (NLEFT.GE.VHRMO(NMONTH)) 
          NLEFT=NLEFT-VHRMO(NMONTH)
          NMONTH=NMONTH+1
        END DO 
        
!
! Sum in the number of days.
!
        NDAY=NLEFT/NHRDA
        NLEFT=NLEFT-NDAY*NHRDA
        NDAY=NDAY+1
!
! Sum in the number of hours.
!
        NHOUR=NLEFT

        END
! ******************************************************************************
!  Purpose:
!     get the three characters abbreviation of month.
!  Input:
!     month: month number
!  Output:
!     month_str: the three characters abbreviation of the month
!  Provided by:
!      Deng Liantang 2004.03.19
! ******************************************************************************
       SUBROUTINE get_month_str(month,month_str)
       IMPLICIT NONE

       integer,          intent(in)  :: month
       character(len=3),intent(out) :: month_str
       character(len=3),dimension(12) :: month_3w
         month_3w(1) = 'JAN'
         month_3w(2) = 'FEB'
         month_3w(3) = 'MAR'
         month_3w(4) = 'APR'
         month_3w(5) = 'MAY'
         month_3w(6) = 'JUN'
         month_3w(7) = 'JUL'
         month_3w(8) = 'AUG'
         month_3w(9) = 'SEP'
         month_3w(10) = 'OCT'
         month_3w(11) = 'NOV'
         month_3w(12) = 'DEC'
         month_str(1:3) = month_3w(month)
       END SUBROUTINE get_month_str
